package com.example.user.utils;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;

import com.example.redis.utils.CacheUtil;
import com.example.user.domain.LoginUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class TokenWorker {

    private static final int expireMinute = 1440; // 设置过期时间默认1天即1440分钟
    protected static final long MILLIS_SECOND = 1000; //秒
    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; //分钟
//    private SignatureAlgorithm alg = SignatureAlgorithm.HS512; // 签名算法(新版jjwt自动配置合适的签名算法)
    private static final String secret = "mis_token_secret_hotel_2022_36_20250512";

    private static final String TOKEN_PREFIX = "Bearer ";  //token前缀

    @Autowired
    private CacheUtil cacheUtil;

    /**
     * 生成token并存入redis
     * @param loginUser
     * @return
     */
    public String generateToken(LoginUser loginUser){
        String subject = loginUser.getUsername()+ IdUtil.getSnowflakeNextIdStr();
        long expireTime = new Date().getTime() + MILLIS_MINUTE * expireMinute;
        String token = createToken(subject, expireTime);
        loginUser.setExpireTime(expireTime);
        System.out.println("登录的用户: " + loginUser);
        cacheUtil.setObject(subject, loginUser, expireMinute);
        return token;
    }

    /**
     * 解析token
     * @param request
     * @return
     */
    public LoginUser getLoginUser(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        LoginUser loginUser = null;
        if(StrUtil.isNotEmpty(token)) {
            Claims claims = parseToken(token);
            String subject = claims.getSubject();
            loginUser = cacheUtil.getObject(subject);
        }
        return loginUser;
    }

    /**
     * 生成token
     * @param subject
     * @param expireTime
     * @return
     */
    public String createToken(String subject,long expireTime) {
        Date issuedAt = new Date(); // 签发时间
        Date expiration = new Date(expireTime); //过期时间
        String token = Jwts.builder()
                .header()
                    .add("typ", "JWT")
                    .and()
                .subject(subject)
                .issuedAt(issuedAt)
                .expiration(expiration)
                .signWith(Keys.hmacShaKeyFor(secret.getBytes()))
                .compact();
        return token;
    }

    /**
     * 解析token
     * @param token
     * @return
     */
    public Claims parseToken(String token) {
        if (StrUtil.isNotEmpty(token) && token.startsWith(TOKEN_PREFIX)){
            token = token.replace(TOKEN_PREFIX, "");
        }
        try {
            return Jwts.parser()
                    .verifyWith(Keys.hmacShaKeyFor(secret.getBytes()))
                    .build()
                    .parseSignedClaims(token)
                    .getPayload();
        } catch (Exception e) {
            return null;
        }
    }

}
